export class Rand {
    constructor(prng = Math.random) {
        this.prng = prng
    }

    position(dim) {
        return [
            Math.floor(this.prng() * dim.width),
            Math.floor(this.prng() * dim.height)
        ]
        // return {x, y} // NOTE: object property shorthand, same as writing { x: x, y: y}
    }

    choice(arr) {
        return arr[Math.floor(this.prng() * arr.length)]
    }
}

export class RandTerrain extends Rand {
    constructor(prng = Math.random) {
        super(prng);
        this.terrains = ['desert', 'forest', 'mountain', 'swamp']
    }

    go() {
        return this.choice(this.terrains)
    }
}


export class Random {
    /**
     * JS实现伪随机数使用随机数种子生成.
     * 实现随机函数的方法很多，如斐波那契法、线性同余法、梅森旋转(Mersenne twister)算法
     * 现在最好的随机数产生算法是梅森旋转算法.
     *
     * 参考:
     * 1. [code]: https://www.xin3721.com/Articlejquery/javascript29934.html
     * 2. [为什么用 9301, 49297, 233280 这三个数字做基数?]: https://www.zhihu.com/question/22818104
     */

    constructor(seed, max = 10) {
        this.seed = (seed || Date.now()) % 999999999;
        this.max = max
    }

    // 取一个随机整数 max=最大值（0开始，不超过该值） 默认10
    next(max) {
        max = max || this.max;
        this.seed = (this.seed * 9301 + 49297) % 233280;
        let val = this.seed / 233280.0;
        return Math.floor(val * max);
    }
}
